# coding=utf-8
import hashlib
import json
import logging
import urllib.request, urllib.error, urllib.parse
import base64
import time

from lib.common import CacheKeys, get_api_result
from django.core.cache import cache
from lib.qiniucloud.qiniuMain import QiNiuService
from project.settings import wx_settings, DOMAIN_URL
from datetime import datetime


class YiJiaoWechat(object):
    _instance = None
    global_access_token_url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={}&secret={}'
    js_access_token_url = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={}&type=jsapi'
    template_url = 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={}'
    logger = logging.getLogger("wechat")

    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(YiJiaoWechat, cls).__new__(cls, *args, **kwargs)
        return cls._instance

    @property
    def access_token(self):
        access_token_cache = cache.get(CacheKeys.ACCESS_TOKEN_WECHAT)
        if not access_token_cache:
            access_token = self.get_access_token()
            if access_token:
                cache.set(CacheKeys.ACCESS_TOKEN_WECHAT, access_token, 6600)
                return access_token
            else:
                return None
        else:
            return access_token_cache

    def get_access_token(self):
        try:
            result = get_api_result(self.global_access_token_url.format(wx_settings.APP_ID, wx_settings.APP_SECRET))
            access_token = result['access_token']
            return access_token
        except KeyError:
            self.logger.error("Wechat service error by get_access_token: {}".format(result['errcode']))
            return None

    @property
    def js_access_token(self):
        js_ticket_cache = cache.get(CacheKeys.JS_ACCESS_TOKEN_WECHAT)
        if not js_ticket_cache:
            js_access_token = self.get_js_access_token()
            if js_access_token:
                cache.set(CacheKeys.JS_ACCESS_TOKEN_WECHAT, js_access_token, 6600)
                return js_access_token
            else:
                return None
        else:
            return js_ticket_cache

    def get_js_access_token(self):
        try:
            result = get_api_result(self.js_access_token_url.format(self.access_token))
            js_ticket = result['ticket']
            return js_ticket
        except KeyError:
            self.logger.error("Wechat service error by get_js_access_token: {}".format(result['errcode']))
            return None

    def send_template_msg(self, openid, report_id, receiver_type='parent'):
        """
        :param openid: openid
        :param report_id: the id of the report which is belong to teacher or parent
        :param receiver_type: teacher or parent
        :return:Nothing
        """
        template_obj = wx_settings.TEMPLATE_ID_DETAIL[2]
        reciver = WechatTemplate.RECEIVER_TYPE[receiver_type]
        # 使用base64 encode 周报id以及类型 格式为 10010,teacher
        # 接口处使用decode再还原回去
        direct_url = "".join((DOMAIN_URL,
                               reciver['s_url'].format(base64.b64encode(",".join([str(report_id), receiver_type])))))
        data = {
            "touser": openid,
            "template_id": template_obj['template_id'],
            "url": direct_url,
            "data": {
                "first": {
                    "value": "尊敬的" + reciver['title'] + "你好，"+reciver['prefix']+"最近一周的学习报告已生成，请您过目。",
                },
                "keyword1": {
                    "value": "学习状况报告",
                },
                "keyword2": {
                    "value": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                },
                "remark": {
                    "value": "点击查看详情，祝您生活愉快。"
                }
            }
        }
        data = json.dumps(data)
        req = urllib.request.Request(self.template_url.format(self.access_token), data)
        response = urllib.request.urlopen(req).read()
        response = json.loads(response)
        if response['errcode'] != 0:
            self.logger.error("Wechat service error by send_template_msg: {}".format(data))

    def send_proxy_template_msg(self, openid, money, after_money):
        """
        :param openid: openid
        :return:Nothing
        """
        template_obj = wx_settings.TEMPLATE_ID_DETAIL[3]
        data = {
            "touser": openid,
            "template_id": template_obj['template_id'],
            "url": '',
            "data": {
                "first": {
                    "value": "您好，您于" + datetime.now().strftime('%Y-%m-%d %H:%M') + " 有一笔奖励金到账:",
                },
                "date": {
                    "value": datetime.now().strftime('%Y-%m-%d %H:%M'),
                },
                "adCharge": {
                    "value": "".join(["￥", str(money)])
                },
                "type": {
                    "value": "奖励金"
                },
                "cashBalance": {
                    "value": "".join(["￥", str(after_money)])
                },
                "remark": {
                    "value": "请到『亿教亿学 学生端APP』查看您的余额和明细。"
                }
            }
        }
        data = json.dumps(data).encode('utf-8')
        req = urllib.request.Request(self.template_url.format(self.access_token), data)
        response = urllib.request.urlopen(req).read()
        response = json.loads(response)
        if response['errcode'] != 0:
            self.logger.error("Wechat service error by send_template_msg: {}".format(data))

    def getWechatConfig(self, url, shareImg=None, surl=None):
        """
        :param url: share url
        :param shareImg: share img
        :param surl: special share url
        :return: WeChat Config detail
        """
        noncestr = QiNiuService.random_str(16)
        timestamp = str(int(time.time()))
        jsapi_ticket = self.js_access_token
        tmpstr = 'jsapi_ticket=' + jsapi_ticket + '&noncestr=' + noncestr + '&timestamp=' + timestamp + '&url=' + url
        signature = hashlib.sha1(tmpstr.encode()).hexdigest()
        data = {
            'timestamp': timestamp,
            'nonceStr': noncestr,
            'url': surl if surl else url,
            'appid': wx_settings.APP_ID,
            'signature': signature,
            'shareImg': shareImg
        }
        return data


class WechatTemplate:
    # STUDENT_REPORT_WEEK_FOR_PARENT参数说明
    # student_name 学生姓名 student_class_name 班级名称
    # 1 暂时废弃
    STUDENT_REPORT_WEEK_FOR_PARENT = {
        "touser": '{openid}',
        "template_id": '{template_id}',
        "url": '{direct_url}',
        "data": {
            "first": {
                "value": "尊敬的{student_name}家长你好，{student_name}最近一周的学习报告已生成，请您过目。",
                "color": "#32a938"
            },
            "keyword1": {
                "value": "{student_class_name}",
                "color": "#32a938"
            },
            "keyword2": {
                "value": "{student_name}" + '\U0001f618' * 3
            },
            "keyword3": {
                "value": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            },
            "keyword4": {
                "value": "亿教亿学党支部"
            },
            "remark": {
                "value": "点击查看详情，祝您生活愉快。"
            }
        }
    }

    STUDENT_REPORT_WEEK_FOR_TEACHER = {
        "touser": '{openid}',
        "template_id": '{template_id}',
        "url": '{direct_url}',
        "data": {
            "first": {
                "value": "尊敬的{person_type}你好，{prefix}最近一周的学习报告已生成，请您过目。",
                "color": "#32a938"
            },
            "keyword1": {
                "value": "学习状况报告",
                "color": "#32a938"
            },
            "keyword2": {
                "value": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            },
            "remark": {
                "value": "点击查看详情，祝您生活愉快。"
            }
        }
    }

    TEMPLATE_ID_TO_CONTENT = {
        1: {
            'id': 1,
            'template_id': 'om5fXWH40bGKEuFrUtSHnxU-FhggcjXszKP4UqKNOBA',
            'content': STUDENT_REPORT_WEEK_FOR_PARENT,
        },
        2: {
            'id': 2,
            'template_id': 'bk_gi7l2SUnpOlyEmGIer5Nn8AW6U1JyFmzjItWjACY',
            'content': STUDENT_REPORT_WEEK_FOR_TEACHER,
        }
    }

    RECEIVER_TYPE = {
        'teacher': {
            'prefix': "您所授班级",
            'title': "老师",
            's_url': "/weekly/teacher/r_key={}"
        },
        'parent': {
            'prefix': "您的孩子",
            'title': "家长",
            's_url': "/weekly/parent/r_key={}"
        }
    }

mm_YiJiaoWechat = YiJiaoWechat()
